"""
CMDB Serializers for REST API
"""
from rest_framework import serializers
from django.contrib.auth.models import User, Group
from django.contrib.auth.password_validation import validate_password
from .models import Host, HostGroup, Project, Environment, UserProfile, EmailConfig, AuditLog, InspectionHistory, Role


class ProjectSerializer(serializers.ModelSerializer):
    """项目序列化器"""
    host_count = serializers.SerializerMethodField()
    
    class Meta:
        model = Project
        fields = ['id', 'name', 'description', 'host_count', 'created_at', 'updated_at']
        read_only_fields = ['created_at', 'updated_at']
    
    def get_host_count(self, obj):
        return obj.hosts.count()


class EnvironmentSerializer(serializers.ModelSerializer):
    """环境序列化器"""
    host_count = serializers.SerializerMethodField()
    
    class Meta:
        model = Environment
        fields = ['id', 'name', 'env_type', 'description', 'host_count', 'created_at', 'updated_at']
        read_only_fields = ['created_at', 'updated_at']
    
    def get_host_count(self, obj):
        return obj.hosts.count()


class HostGroupSerializer(serializers.ModelSerializer):
    """主机组序列化器"""
    host_count = serializers.SerializerMethodField()
    
    class Meta:
        model = HostGroup
        fields = ['id', 'name', 'description', 'host_count', 'created_at', 'updated_at']
        read_only_fields = ['created_at', 'updated_at']
    
    def get_host_count(self, obj):
        return obj.hosts.count()


class HostSerializer(serializers.ModelSerializer):
    """主机序列化器"""
    project_name = serializers.CharField(source='project.name', read_only=True, allow_null=True)
    environment_name = serializers.CharField(source='environment.name', read_only=True, allow_null=True)
    host_group_name = serializers.CharField(source='host_group.name', read_only=True, allow_null=True)
    
    class Meta:
        model = Host
        fields = [
            'id', 'name', 'ip', 'mac_address', 'ipmi_address', 'ipmi_username', 'ipmi_password',
            'port', 'username', 'auth_type', 
            'password', 'ssh_key', 'project', 'project_name',
            'environment', 'environment_name', 'host_group', 'host_group_name',
            'status', 'description', 
            # 系统信息字段
            'os_type', 'os_version', 'os_kernel',
            'cpu_cores', 'cpu_arch', 'cpu_model',
            'memory_total', 'memory_used', 'memory_info',
            'disk_total', 'disk_used', 'disk_info',
            'public_ip', 'private_ip',
            'info_collected_at',
            'created_at', 'updated_at'
        ]
        read_only_fields = ['created_at', 'updated_at']
        extra_kwargs = {
            'name': {'required': True, 'allow_blank': False},
            'ip': {'required': True, 'allow_blank': False},
            'username': {'required': True, 'allow_blank': False},
            'password': {'required': False, 'allow_blank': True, 'allow_null': False, 'default': ''},
            'ssh_key': {'required': False, 'allow_blank': True, 'allow_null': False, 'default': ''},
            'mac_address': {'required': False, 'allow_blank': True, 'allow_null': False, 'default': ''},
            'ipmi_address': {'required': False, 'allow_null': True},
            'ipmi_username': {'required': False, 'allow_blank': True, 'allow_null': False, 'default': ''},
            'ipmi_password': {'required': False, 'allow_blank': True, 'allow_null': False, 'default': ''},
            'project': {'required': False, 'allow_null': True},
            'environment': {'required': False, 'allow_null': True},
            'host_group': {'required': False, 'allow_null': True},
            'description': {'required': False, 'allow_blank': True, 'allow_null': False, 'default': ''},
        }
    
    def validate(self, attrs):
        """自定义验证"""
        auth_type = attrs.get('auth_type', 'password')
        
        # 将null值转换为空字符串（针对CharField字段）
        string_fields = ['mac_address', 'ipmi_username', 'ipmi_password', 'password', 'ssh_key', 'description']
        for field in string_fields:
            if field in attrs and attrs[field] is None:
                attrs[field] = ''
        
        # 验证认证信息
        if auth_type == 'password':
            if not attrs.get('password') and not self.instance:
                raise serializers.ValidationError({'password': '密码认证方式必须提供密码'})
        elif auth_type == 'key':
            if not attrs.get('ssh_key') and not self.instance:
                raise serializers.ValidationError({'ssh_key': '密钥认证方式必须提供SSH密钥'})
        
        return attrs
    
    def to_representation(self, instance):
        """
        序列化时对敏感信息进行处理
        返回占位符而不是真实密码
        """
        representation = super().to_representation(instance)
        
        # 如果有密码，返回占位符
        if instance.password:
            representation['password'] = '******'
        
        # 如果有SSH密钥，返回占位符
        if instance.ssh_key:
            representation['ssh_key'] = '******'
        
        # 如果有IPMI密码，返回占位符
        if instance.ipmi_password:
            representation['ipmi_password'] = '******'
        
        return representation
    
    def update(self, instance, validated_data):
        """
        更新主机信息
        如果密码或SSH密钥为占位符或空字符串，则保留原有值
        """
        # 如果密码为占位符或空字符串，则保留原密码
        password = validated_data.get('password', '')
        if password == '' or password == '******':
            validated_data.pop('password', None)
        
        # 如果SSH密钥为占位符或空字符串，则保留原密钥
        ssh_key = validated_data.get('ssh_key', '')
        if ssh_key == '' or ssh_key == '******':
            validated_data.pop('ssh_key', None)
        
        # 如果IPMI密码为占位符或空字符串，则保留原密码
        ipmi_password = validated_data.get('ipmi_password', '')
        if ipmi_password == '' or ipmi_password == '******':
            validated_data.pop('ipmi_password', None)
        
        # 执行标准更新
        for attr, value in validated_data.items():
            setattr(instance, attr, value)
        instance.save()
        return instance


class UserProfileSerializer(serializers.ModelSerializer):
    """用户扩展信息序列化器"""
    class Meta:
        model = UserProfile
        fields = ['can_use_ssh', 'phone', 'department', 'avatar']


class UserSerializer(serializers.ModelSerializer):
    """用户序列化器"""
    profile = UserProfileSerializer(read_only=True)
    can_use_ssh = serializers.BooleanField(source='profile.can_use_ssh', read_only=True)
    avatar = serializers.CharField(source='profile.avatar', read_only=True)
    
    class Meta:
        model = User
        fields = ['id', 'username', 'email', 'first_name', 'last_name', 
                  'is_active', 'is_staff', 'is_superuser', 'date_joined', 'last_login',
                  'profile', 'can_use_ssh', 'avatar']
        read_only_fields = ['date_joined', 'last_login', 'is_superuser']


class UserDetailSerializer(serializers.ModelSerializer):
    """用户详情序列化器（用于更新权限）"""
    can_use_ssh = serializers.BooleanField(required=False)
    phone = serializers.CharField(required=False, allow_blank=True)
    department = serializers.CharField(required=False, allow_blank=True)
    avatar = serializers.CharField(required=False, allow_blank=True)
    
    class Meta:
        model = User
        fields = ['id', 'username', 'email', 'first_name', 'last_name', 
                  'is_active', 'can_use_ssh', 'phone', 'department', 'avatar']
    
    def update(self, instance, validated_data):
        # 提取UserProfile字段
        can_use_ssh = validated_data.pop('can_use_ssh', None)
        phone = validated_data.pop('phone', None)
        department = validated_data.pop('department', None)
        avatar = validated_data.pop('avatar', None)
        
        # 更新User字段
        for attr, value in validated_data.items():
            setattr(instance, attr, value)
        instance.save()
        
        # 更新或创建UserProfile
        profile, created = UserProfile.objects.get_or_create(user=instance)
        if can_use_ssh is not None:
            profile.can_use_ssh = can_use_ssh
        if phone is not None:
            profile.phone = phone
        if department is not None:
            profile.department = department
        if avatar is not None:
            profile.avatar = avatar
        profile.save()
        
        return instance


class RegisterSerializer(serializers.ModelSerializer):
    """用户注册序列化器"""
    password = serializers.CharField(write_only=True, required=True, validators=[validate_password])
    password2 = serializers.CharField(write_only=True, required=False, label='确认密码')
    is_superuser = serializers.BooleanField(required=False, default=False)
    
    class Meta:
        model = User
        fields = ['username', 'password', 'password2', 'email', 'first_name', 'last_name', 'is_superuser']
        extra_kwargs = {
            'email': {'required': False},
        }
    
    def validate(self, attrs):
        if 'password2' in attrs and attrs.get('password') != attrs.get('password2'):
            raise serializers.ValidationError({"password": "两次密码不一致"})
        return attrs
    
    def create(self, validated_data):
        validated_data.pop('password2', None)
        is_superuser = validated_data.pop('is_superuser', False)
        
        user = User.objects.create_user(**validated_data)
        if is_superuser:
            user.is_superuser = True
            user.is_staff = True
            user.save()
        
        # 创建用户扩展信息，默认不能使用SSH
        UserProfile.objects.create(user=user, can_use_ssh=False)
        return user


class LoginSerializer(serializers.Serializer):
    """登录序列化器"""
    username = serializers.CharField(required=True)
    password = serializers.CharField(required=True, write_only=True)


class GroupSerializer(serializers.ModelSerializer):
    """用户组序列化器"""
    user_count = serializers.SerializerMethodField()
    
    class Meta:
        model = Group
        fields = ['id', 'name', 'user_count']
    
    def get_user_count(self, obj):
        return obj.user_set.count()


class EmailConfigSerializer(serializers.ModelSerializer):
    """邮箱配置序列化器"""
    username = serializers.CharField(source='user.username', read_only=True)
    
    class Meta:
        model = EmailConfig
        fields = [
            'id', 'user', 'username', 'email_provider', 'email_address', 
            'smtp_server', 'smtp_port', 'use_ssl', 'authorization_code', 
            'is_active', 'created_at', 'updated_at'
        ]
        read_only_fields = ['user', 'created_at', 'updated_at']
        extra_kwargs = {
            'authorization_code': {'write_only': False},  # 授权码可读写
        }
    
    def validate_email_address(self, value):
        """验证邮箱地址格式"""
        if not value:
            raise serializers.ValidationError("邮箱地址不能为空")
        return value
    
    def validate_authorization_code(self, value):
        """验证授权码"""
        if not value:
            raise serializers.ValidationError("授权码不能为空")
        if len(value) < 6:
            raise serializers.ValidationError("授权码长度不能少于6位")
        return value


class AuditLogSerializer(serializers.ModelSerializer):
    """审计日志序列化器"""
    username = serializers.CharField(source='user.username', read_only=True, allow_null=True)
    resolved_by_username = serializers.CharField(source='resolved_by.username', read_only=True, allow_null=True)
    level_display = serializers.CharField(source='get_level_display', read_only=True)
    action_display = serializers.CharField(source='get_action_display', read_only=True)
    
    class Meta:
        model = AuditLog
        fields = [
            'id', 'timestamp', 'level', 'level_display', 'action', 'action_display',
            'host', 'host_ip', 'host_name', 'resource_type', 'resource_value', 'threshold',
            'title', 'message', 'user', 'username', 'extra_data',
            'is_resolved', 'resolved_at', 'resolved_by', 'resolved_by_username'
        ]
        read_only_fields = ['timestamp']


class InspectionHistorySerializer(serializers.ModelSerializer):
    """巡检历史序列化器"""
    host_name = serializers.CharField(source='host.name', read_only=True)
    host_ip = serializers.CharField(source='host.ip', read_only=True)
    
    class Meta:
        model = InspectionHistory
        fields = [
            'id', 'host', 'host_name', 'host_ip', 'timestamp',
            'cpu_usage', 'cpu_core_count', 'cpu_frequency',
            'memory_usage', 'memory_total', 'memory_used', 'memory_available',
            'disk_usage', 'disk_total', 'disk_used', 'disk_free', 'disk_mount_point',
            'status', 'has_warning'
        ]
        read_only_fields = ['timestamp']


class RoleSerializer(serializers.ModelSerializer):
    """角色序列化器"""
    permission_count = serializers.SerializerMethodField()
    user_group_ids = serializers.ListField(
        child=serializers.IntegerField(),
        required=False,
        allow_empty=True,
        write_only=True
    )
    user_group_ids_display = serializers.SerializerMethodField(read_only=True)
    user_groups = serializers.SerializerMethodField()
    
    class Meta:
        model = Role
        fields = [
            'id', 'name', 'description', 'role_type', 'permissions',
            'permission_count', 'user_group_ids', 'user_group_ids_display', 'user_groups',
            'created_at', 'updated_at'
        ]
        read_only_fields = ['created_at', 'updated_at']
    
    def to_internal_value(self, data):
        """在验证之前记录接收到的数据"""
        print(f"[RoleSerializer.to_internal_value] 接收到的原始数据: {data}")
        result = super().to_internal_value(data)
        print(f"[RoleSerializer.to_internal_value] 验证后的数据: {result}")
        return result
    
    def get_permission_count(self, obj):
        """获取权限数量"""
        return obj.permission_count
    
    def get_user_group_ids_display(self, obj):
        """获取关联的用户组ID列表（用于显示）"""
        return list(obj.user_groups.values_list('id', flat=True))
    
    def get_user_groups(self, obj):
        """获取关联的用户组名称列表"""
        return list(obj.user_group_names)
    
    def create(self, validated_data):
        print(f"[RoleSerializer.create] validated_data: {validated_data}")
        user_group_ids = validated_data.pop('user_group_ids', [])
        print(f"[RoleSerializer.create] user_group_ids: {user_group_ids}")
        
        role = Role.objects.create(**validated_data)
        print(f"[RoleSerializer.create] 角色已创建: {role.id}, {role.name}")
        
        if user_group_ids:
            role.user_groups.set(user_group_ids)
            print(f"[RoleSerializer.create] 已设置用户组: {user_group_ids}")
            print(f"[RoleSerializer.create] 实际关联的用户组: {list(role.user_groups.values_list('id', 'name'))}")
        
        return role
    
    def update(self, instance, validated_data):
        print(f"[RoleSerializer.update] validated_data: {validated_data}")
        user_group_ids = validated_data.pop('user_group_ids', None)
        print(f"[RoleSerializer.update] user_group_ids: {user_group_ids}")
        
        for attr, value in validated_data.items():
            setattr(instance, attr, value)
        instance.save()
        print(f"[RoleSerializer.update] 角色已更新: {instance.id}, {instance.name}")
        
        if user_group_ids is not None:
            instance.user_groups.set(user_group_ids)
            print(f"[RoleSerializer.update] 已设置用户组: {user_group_ids}")
            print(f"[RoleSerializer.update] 实际关联的用户组: {list(instance.user_groups.values_list('id', 'name'))}")
        
        return instance
